/** *************************************************************************
 *  @file       basic_cfg.c
 *  @brief	    基础配置函数
 *  @date		2021/04/24 
 *  @author		junshuai.li
 *  @version	0.0.1
 ****************************************************************************/
#include "local_cfg.h"
#include "../basic_cfg/basic_cfg.h"


//定义最大配置内容数量，共8bit
#define MAX_CFG_DATA_NUM 256



//解析规划配置中交换机的addr和data
int parse_plan_entry(cJSON *entry_json,u32 *addr,u32 *data,u16 *plan_cfg_data_idx)
{
	cJSON *addr_json=NULL;
	cJSON *data_json=NULL;
	cJSON *tmp_json=NULL;

	int array_num = 0;
	int i = 0;

	u32 tvalue32 = 0;

	// 获取addr信息
	addr_json =cJSON_GetObjectItem(entry_json, "addr");

	if(NULL == addr_json)
	{
		printf("can not find  addr object!\n");
		return -1;
	}
	else
	{
		sscanf(addr_json->valuestring,"%x",&tvalue32);
		printf("addr：%x \n",tvalue32);
		*addr = htonl(tvalue32);
		//*addr = tvalue32;
	}

	// 获取data信息
	data_json =cJSON_GetObjectItem(entry_json, "data");

	if(NULL == data_json)
	{
		printf("can not find  data object!\n");
		return -1;
	}
	else
	{
		//有多个data情况
		if(data_json->type == cJSON_Array)
		{
			array_num = cJSON_GetArraySize(data_json);
			printf("array_num = %d \n", array_num);

			if(array_num == 0)
			{
				printf("parse_plan_entry, array_num = 0! \n");
				return -1;
			}

			for (i = 0; i < array_num; i++)
			{
				tmp_json = cJSON_GetArrayItem(data_json,i);

				if (!tmp_json) 
				{
					printf("parse_plan_entry data_json error, Error before: [%s]\n",cJSON_GetErrorPtr());
					return -1;
				}

				sscanf(tmp_json->valuestring,"%x",&tvalue32);			
				printf("data：%x \n",tvalue32);

				data[*plan_cfg_data_idx]=htonl(tvalue32);
				//data[*plan_cfg_data_idx]=tvalue32;
				(*plan_cfg_data_idx)++;
			}
		}
		else
		{
			sscanf(data_json->valuestring,"%x",&tvalue32);			
			printf("data：%x \n",tvalue32);

			data[*plan_cfg_data_idx]=htonl(tvalue32);
			//data[*plan_cfg_data_idx]=tvalue32;
			(*plan_cfg_data_idx)++;
		}
	
	}
    	
	return 0;
}


/* 解析switch内容，提取出lid和entry */  
 int plan_cfg_and_parse_node_object(cJSON *node_json,u8 *pkt)
{  
	int ret = 0;
	u16 hcp_mid = 0;
	u8 local_mac[6] = {0};
	u8 cmp_mac[6] = {0};
	
	u32 addr = 0;

	u32 *plan_cfg_data 		= NULL;//定义离线规划配置内容的指针
	u16  plan_cfg_data_idx 	= 0;//定义数组的索引值

	int array_num = 0;
	int i = 0;
	u16 tvalue16 = 0;
		
	cJSON *hcp_mid_json=NULL;
	cJSON *entry_json=NULL;
	cJSON *tmp_entry_json=NULL;


	if(pkt == NULL)
	{
		printf("plan_cfg_and_parse_node_object,pkt = NULL! \n");
		return -1;
	}


	//sizeof(tsmp_header)表示TSMP头、sizeof(tsmp_set_req_or_get_res_pkt_data)表示NMAC头
	plan_cfg_data = (u32 *)(pkt + sizeof(tsmp_header) + sizeof(tsmp_set_req_or_get_res_pkt_data));//配置的数据

	// 获取节点hcp_mid信息
	hcp_mid_json =cJSON_GetObjectItem(node_json, "hcp_mid");

	if(NULL == hcp_mid_json)
	{
		printf("can not find  hcp_mid object!\n");
		return -1;
	}
	else
	{
		sscanf(hcp_mid_json->valuestring, "%hx", &tvalue16);
		hcp_mid = tvalue16;
		
		printf("hcp_mid 0x%hx \n", hcp_mid);
		get_hcp_mac_from_mid(local_mac,hcp_mid);
		
	}

	//验证是否已正确获取local_mac，如果是则可以继续运行
	if(memcmp(local_mac,cmp_mac,6) == 0)
	{
		printf("error:cfg local_mac is 0\n");
		return -1;
	}

	// 获取节点entry信息
	entry_json =cJSON_GetObjectItem(node_json, "entry");

	if(NULL == entry_json)
	{
		printf("can not find  entry object!\n");
		return -1;
	}
	else
	{
		//有多个entry情况
		if(entry_json->type == cJSON_Array)
		{
			array_num = cJSON_GetArraySize(entry_json);
			printf("array_num = %d \n", array_num);

			if(array_num == 0)
			{
				printf("plan_cfg_and_parse_node_object, array_num = 0! \n");
				return -1;
			}

			for (i = 0; i < array_num; i++)
			{
				tmp_entry_json = cJSON_GetArrayItem(entry_json,i);

				if (!tmp_entry_json) 
				{
					printf("plan_cfg_and_parse_node_object entry_json error, Error before: [%s]\n",cJSON_GetErrorPtr());
					return -1;
				}
				
				//解析entry
				parse_plan_entry(tmp_entry_json,&addr,plan_cfg_data,&plan_cfg_data_idx);
				if(plan_cfg_data_idx != 0)
				{
					tsmp_set_req(local_mac,plan_cfg_data_idx,addr,pkt);//写请求
				
					//配置验证
					ret = cfg_varify(local_mac,plan_cfg_data_idx,addr,pkt);
		
					//配置验证失败，程序退出
					if(ret == -1)
					{
						return -1;
					}
					
					//验证完成后清零复位
					plan_cfg_data_idx = 0;
				}
			}
		}
		else if(entry_json->type == cJSON_Object)
		{
			//解析entry
			parse_plan_entry(entry_json,&addr,plan_cfg_data,&plan_cfg_data_idx);
			if(plan_cfg_data_idx != 0)
			{
				tsmp_set_req(local_mac,plan_cfg_data_idx,addr,pkt);//写请求
			
				//配置验证
				ret = cfg_varify(local_mac,plan_cfg_data_idx,addr,pkt);
	
				//配置验证失败，程序退出
				if(ret == -1)
				{
					return -1;
				}
				
				//验证完成后清零复位
				plan_cfg_data_idx = 0;
			}
		}	
		
	}

	printf("debug222222222222\n");

    return 0;  
	
}

 int plan_cfg_and_parse_node(char* buf,u8 *pkt)
 {
	 int ret = 0;
	 int array_num = 0;
	 int i = 0;
	 u16 tvalue16 = 0;
	 
	 cJSON *root_json=NULL;
	 cJSON *network_plan_cfg_json=NULL;
 
	 cJSON *node_json=NULL;
	 cJSON *tmp_json=NULL;
	 
	 riprt_n(buf);
	 root_json=cJSON_Parse(buf);
 
	 if (!root_json) 
	 {
		 printf("parse root_json error, Error before: [%s]\n",cJSON_GetErrorPtr());
		 return -1;
	 }
	 
	 network_plan_cfg_json = cJSON_GetObjectItem(root_json, "network_plan_cfg");
	 if (!network_plan_cfg_json) 
	 {
		 printf("parse network_plan_cfg error, Error before: [%s]\n",cJSON_GetErrorPtr());
		 cJSON_Delete(root_json);
		 return -1;
	 }
 
	 node_json = cJSON_GetObjectItem(network_plan_cfg_json, "node");
	 if (!node_json) 
	 {
		 printf("parse node_json error, Error before: [%s]\n",cJSON_GetErrorPtr());
		 cJSON_Delete(root_json);
		 return -1;
	 }
 
	 //有多个节点情况
	 if(node_json->type == cJSON_Array)
	 {
		 array_num = cJSON_GetArraySize(node_json);
		 printf("array_num = %d \n", array_num);
 
		 if(array_num == 0)
		 {
			 printf("parse_plan_info, node = NULL! \n");
			 cJSON_Delete(root_json);
			 return -1;
		 }
 
		 for (i = 0; i < array_num; i++)
		 {
			 tmp_json = cJSON_GetArrayItem(node_json,i);
 
			 if (!tmp_json) 
			 {
				 printf("parse plan_node_entry_json error, Error before: [%s]\n",cJSON_GetErrorPtr());
				 cJSON_Delete(root_json);
				 return -1;
			 }
 
			 //获取单个节点的规划信息
			 ret = plan_cfg_and_parse_node_object(tmp_json,pkt);
			 if(ret == -1)
			 {
				 printf("plan_cfg_and_parse_node_object error!\n");
				 cJSON_Delete(root_json);
				 return -1;
			 }
		 }
	 }
	 else if(node_json->type == cJSON_Object)
	 {
		 //获取单个节点的基础信息
		 ret = plan_cfg_and_parse_node_object(node_json,pkt);
	 }
 
	 cJSON_Delete(root_json);
	 
	 return ret;
	 
 }


int plan_cfg_and_parse_file(u8 *docname,u8 *pkt)
{	
 	int ret = 0;
	
	FILE *fp;
	char *buf;
	fp = fopen(docname,"r");

	if(fp == NULL)
	{
		printf("fopen %s error\n",docname);
		return -1;
	}
			
    // 确定文件大小, 并将读取指针移回文件开始
    fseek(fp, 0, SEEK_END);
    long pos = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    if (pos <= 0) 
	{
        printf("%s Invalid!\n",docname);
		fclose(fp);
		return -1;
    }
	
    // 根据文件大小申请内存空间, 注意这边要多申请1个字节用于存放'\0'
    buf = (char*)malloc(pos + 1);
    if (buf == NULL) {
        printf("No enough memory.");
    }
	bzero(buf, pos + 1);
	
    // 读取文件内容至buff
    int nread = fread(buf, pos, 1, fp);
    if (!nread) {
        printf("Failed to read the config file.");
		return -1;
    }

    //解析json，获取各个节点规划配置信息
	ret = plan_cfg_and_parse_node(buf,pkt);

	if(buf != NULL)
	{
		free(buf);
	}
	
    // 关闭文件
	fclose(fp);

	return ret;

}

int is_tsn_plan_cfg_exist()
{
	if(access(OFFLINE_PLAN_JSON_FILE,0) == -1)
    {
    	return 0;
    }
	else
	{
		return 1;
	}

	return 0;
}

//离线规划配置的入口函数
int local_cfg()
{
	int ret = 0;
	
	//申请空间，用于构造配置报文
	u8 *pkt = (u8 *)malloc(MAX_PKT_LEN);
	bzero(pkt,MAX_PKT_LEN);

	while(1)
	{
		ret = is_tsn_plan_cfg_exist();
		if(ret == 1)
		{
			printf("OFFLINE_PLAN_JSON_FILE is exist!\n");
			break;
		}

		sleep(3);
	}
	
	//解析配置文本，并进行配置	
	ret = plan_cfg_and_parse_file(OFFLINE_PLAN_JSON_FILE,pkt);
	if(ret == -1)
	{
		printf("parse_offline_plan_cfg_file fail\n");
		return -1;
	}	
	
 	
	printf("*************enter SYNC_INIT_S********************\n");
	write_debug_msg("*************enter SYNC_INIT_S********************\n");
	free(pkt);

	return 0;
}
	

